package com.lebang.controller.api.shanhu;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.lebang.common.Require;
import com.lebang.component.RedisClient;
import com.lebang.domain.MemberPointInfo;
import com.lebang.domain.ShanhuBussOrder;
import com.lebang.entity.RequestHeaders;
import com.lebang.model.ShanHuBussRecord;
import com.lebang.model.ShanVo;
import com.lebang.model.back.ShanHuBack;
import com.lebang.model.enums.buss.TaskCategory;
import com.lebang.service.MemberNoticeService;
import com.lebang.service.PointService;
import com.lebang.service.buss.MemberService;
import com.lebang.service.buss.ShanHuBussService;
import com.lebangweb.common.TextUtil;
import com.lebangweb.common.UUIDUtil;
import com.lebangweb.encrypt.MessageDigestUtil;
import com.lebangweb.response.Callback;
import com.lebangweb.response.JsonData;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.net.URLDecoder;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @Author: hwq
 * @Date: 2020/5/11 15:52
 * @Version 1.0
 */
@RestController
@RequestMapping("/shanhu")
public class OpenShanHuApi {
    @Autowired
    private RedisClient redisClient;
    @Autowired
    private PointService pointService;
    @Autowired
    private ShanHuBussService shanHuBussService;
    @Autowired
    private MemberNoticeService memberNoticeService;
    @Autowired
    private MemberService memberService;

    @Require
    @PostMapping("/token")
    public JsonData creatToken(HttpServletRequest request) {
        RequestHeaders headers = new RequestHeaders(request);
        String login_key = UUIDUtil.L();
        redisClient.setex(headers.getUserid(), 60 * 60, login_key);
        return Callback.success("success", "成功", login_key);
    }

    @PostMapping("/check")
    public JSONObject login(HttpServletRequest request, String account_id, String login_key, String channel_id) {
        JSONObject jsonObject = new JSONObject();
        int loginStatus;
        jsonObject.put("channel_id", channel_id);
        jsonObject.put("account_id", account_id);
        if (this.check(account_id, login_key)) {
            loginStatus = 0;
        } else {
            loginStatus = 3;
        }
        jsonObject.put("login_status", loginStatus);
        System.out.println(jsonObject.toJSONString());
        return jsonObject;
    }

    /**
     * 查询金币
     *
     * @return
     */
    @ApiOperation("查询金币")
    @PostMapping("/cash")
    public JSONObject cash(HttpServletRequest request) {
        ShanVo vo = this.checkMD5(request);
        ShanHuBussRecord record=vo.getRecord();
        if (this.check(record.getAccountid(), record.getLoginkey()) && vo.isStatus()) {
            String memberId = record.getAccountid();
            MemberPointInfo info = pointService.getWallet(memberId);
            return ShanHuBack.TOTALSUCCESS(info.getCount());
        } else {
            return ShanHuBack.FAIL("签名错误");
        }
    }


    @PostMapping("/sub")
    public JSONObject sub(HttpServletRequest request) {
        String UUID = UUIDUtil.NS();
        int left_coin = 0;
        String msg = "";
        String payno = "";
        ShanVo vo = this.checkMD5(request);
        ShanHuBussRecord record=vo.getRecord();
        try {
            String has = memberService.checkMemberByMemberId(record.getAccountid());
            System.out.println(has);
            if (has != null && this.check(record.getAccountid(), record.getLoginkey()) && vo.isStatus()) {
                String memberId = record.getAccountid();
                MemberPointInfo info = pointService.getWallet(memberId);
                if (info.getCount() < record.getCoinnum()) {
                    return ShanHuBack.FAIL("余额不足");
                } else {
                    ShanhuBussOrder order = shanHuBussService.selectByOrderId(record.getOrderid());
                    if (order != null) {
                        return ShanHuBack.FAIL("订单已存在");
                    } else {
                        boolean status = redisClient.tryGetDistributedLock("lock:shanhubuss:" + record.getOrderid(), UUID, 10000);
                        if (!status) {
                            return ShanHuBack.FAIL("订单处理中");
                        } else {
                            ShanhuBussOrder shanhuBussOrder = new ShanhuBussOrder(record);
                            shanhuBussOrder.setReason(URLDecoder.decode(record.getReason(),"utf-8"));
                            shanHuBussService.insertModel(shanhuBussOrder);
                            pointService.pointCash(shanhuBussOrder.getMemberId(), shanhuBussOrder.getCoinnum(), "珊瑚商城兑换", URLDecoder.decode(record.getReason(),"utf-8")+"[-"+shanhuBussOrder.getCoinnum()+"]");
                            memberNoticeService.addNoticeAndPush("兑换成功", record.getReason(), shanhuBussOrder.getMemberId(), JSON.parseObject(record.getBizdata(), RequestHeaders.class));
                            payno = shanhuBussOrder.getId().toString();
                            left_coin = info.getCount() - record.getCoinnum();
                            return ShanHuBack.SUCCESS(left_coin, "订单接收成功", payno);
                        }
                    }
                }
            } else {
                return ShanHuBack.FAIL("签名错误");
            }
        } catch (Exception e) {
            msg = e.toString();
            return ShanHuBack.FAIL(msg);
        } finally {
            if(!TextUtil.isEmpty(record.getOrderid())){
                redisClient.releaseDistributedLock("lock:shanhubuss:" + record.getOrderid(), UUID);
            }
        }
    }

    @PostMapping("/back")
    public JSONObject back(HttpServletRequest request) {
        String UUID = UUIDUtil.NS();
        ShanVo vo = this.checkMD5(request);
        ShanHuBussRecord record = vo.getRecord();
        try {
            String has = memberService.checkMemberByMemberId(record.getAccountid());
            if (has != null  && vo.isStatus()) {
                ShanhuBussOrder order = shanHuBussService.selectById(Integer.valueOf(record.getPayno()));
                if (order == null) {
                    return ShanHuBack.FAIL("订单不存在");
                }
                if (!order.getMemberId().equals(record.getAccountid())) {
                    return ShanHuBack.FAIL("订单不属于该用户");
                }
                MemberPointInfo info = pointService.getWallet(order.getMemberId());

                if (order.getStatus() == 0) {
                    return ShanHuBack.SUCCESS(info.getCount(), "已返还过积分", "");
                }
                boolean status = redisClient.tryGetDistributedLock("lock:shanhubackbuss:" + record.getOrderid(), UUID, 10000);
                if (!status) {
                    return ShanHuBack.FAIL("订单处理中");
                }
                order.setStatus(0);
                order.setModifyTime(LocalDateTime.now());
                shanHuBussService.updateById(order);
                pointService.addPoint(order.getMemberId(), order.getCoinnum(), TaskCategory.SHAN_HU_BUSS,
                        new RequestHeaders(), "返还积分:"+order.getCoinnum()+"["+order.getReason()+"]");
                return ShanHuBack.SUCCESS(info.getCount(), "订单返还成功", "");
            } else {
                return ShanHuBack.FAIL("签名错误");
            }
        } catch (Exception e) {
            return ShanHuBack.FAIL(e.toString());
        } finally {
            if (!TextUtil.isEmpty(record.getOrderid())) {
                redisClient.releaseDistributedLock("lock:shanhubuss:" + record.getOrderid(), UUID);
            }
        }
    }
    public boolean check(String accountId, String loginKey) {
        String myLoginKey = redisClient.get(accountId);
        if (myLoginKey == null) {
            return false;
        }
        System.out.println(loginKey);
        System.out.println(myLoginKey);
        return loginKey.equals(myLoginKey);
    }

    public ShanVo checkMD5(HttpServletRequest request) {
        ShanHuBussRecord  record=new ShanHuBussRecord();
        ShanVo ShanVo=new ShanVo();
        BufferedReader bufferReaderBody = null;
        JSONObject jsonObject = new JSONObject();
        try {
            bufferReaderBody = new BufferedReader(request.getReader());
            String postData = bufferReaderBody.readLine();
            System.out.println("xxx:  "+postData);
            jsonObject = JSON.parseObject(postData, Feature.OrderedField);
              record = JSON.parseObject(postData, ShanHuBussRecord.class);
        } catch (IOException e) {

        } finally {
            if (bufferReaderBody != null) {
                try {
                    bufferReaderBody.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        StringBuilder sb = new StringBuilder();
        Set<String> keyset = jsonObject.keySet();


        for (String k : keyset) {
            //5.获取当前key
            String value = jsonObject.get(k).toString();
            if ("loginkey".equals(k) || "token".equals(k) || "appid".equals(k)||"appsign".equals(k)||"timestamp".equals(k)) {
                continue;
            }
//            if(k.equals("reason")){
//                try {
//                    value= URLDecoder.decode(value, "utf-8");
//                } catch (UnsupportedEncodingException e) {
//                    e.printStackTrace();
//                }
//            }
            sb.append(k).append("=").append(value).append(";");
        }
        sb.append("HB~4RAHogMA").append(record.getTimestamp());
        System.out.println("mdstr:" + sb.toString());
        String mySign="";
        try {
             mySign=MessageDigestUtil.encryptMD5(sb.toString().getBytes());
            System.out.println("mysign:" + mySign);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("sign1:" + record.getAppsign());
        boolean is=mySign.equalsIgnoreCase(record.getAppsign());
        try {
            return new ShanVo(is,record);
        } catch (Exception e) {
            e.printStackTrace();
            return new ShanVo(false,record);
        }

    }

    public static Map<String, String> getParameter(String params) {
        Map<String, String> map = new HashMap<String, String>();
        try {
            final String charset = "utf-8";
            String[] keyValues = params.split("&");
            for (int i = 0; i < keyValues.length; i++) {
                String key = keyValues[i].substring(0, keyValues[i].indexOf("="));
                String value = keyValues[i].substring(keyValues[i].indexOf("=") + 1);
                map.put(key, value);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }


}
